<?php
/**
 * Application Debug Panel Plugin
 * This plugin keeps track of various pieces of useful information throughout
 * the application life-cycle and makes it available to the user.
 *
 * @package     Visi
 * @subpackage  Controller Plugins
 * @author      Luke Visinoni <luke.visinoni@gmail.com>
 * @copyright   (c) 2010 Luke Visinoni <luke.visinoni@gmail.com>
 * @version     $Id$
 * @todo        Right now this is only capable of displaying debug info
 *              within a placeholder in the layout. Eventually I'd like it
 *              to be flexible enough that I could choose to display it with
 *              firePHP, a log file, or a number of other things.
 */
class Visi_Controller_Plugin_Debug extends Zend_Controller_Plugin_Abstract {

    const LEVEL_DEVELOPMENT = 'development';
    
    const LEVEL_PRODUCTION = 'production';
    
    const PLACEHOLDER = '<!-- DEBUG_PANEL -->';
    
    protected $_level;
    
    protected $_options = array(
        'template' => 'elements/debug.phtml', // the template that is used to render the panel
        'sql_profiler' => true, // toggle SQL profiler which keeps track of queries
        'css' => array(), // an array of css files to include
        'js' => array(), // an array of javascript files to include
    );
    
    protected $_session;
    
    protected $_view;
    
    /**
     * @todo Need to not hard-code the path here
     */
    public function __construct($view, $level, $options = array()) {
    
        $this->setDebugLevel($level)
             ->setOptions($options)
             ->setView($view);
    
    }
    
    public function setView($view) {
    
        foreach ((array) $this->getOption('css') as $stylesheet) {
            $view->headLink()->appendStylesheet($stylesheet);
        }
        foreach ((array) $this->getOption('js') as $javascript) {
            $view->headScript()->appendFile($javascript);
        }
        $this->_view = $view;
        return $this;
    
    }
    
    public function setDebugLevel($level) {
    
        $this->_level = (string) $level;
        return $this;
    
    }
    
    public function setSession(Zend_Session_Namespace $session) {
    
        $this->_session = $session;
        return $this;
    
    }
    
    public function getSession() {
    
        return $this->_session;
    
    }
    
    public function getOption($option) {
    
        if (array_key_exists($option, $this->_options)) {
            return $this->_options[$option];
        }
        throw new Visi_Controller_Plugin_Exception("Option \"{$option}\" doesn't exist.");
    
    }
    
    public function setOption($option, $value) {
    
        if (array_key_exists($option, $this->_options)) {
            $this->_options[$option] = $value;
        }
        throw new Visi_Controller_Plugin_Exception("Option \"{$option}\" doesn't exist.");
    
    }
    
    /**
     * @todo Maybe this should accept arrays as well as Zend_Config instances?
     */
    public function setOptions(Array $options) {
    
        $this->_options = array_merge($this->_options, $options);
        return $this;
    
    }
    
    public function preDispatch(Zend_Controller_Request_Abstract $request) {
    
        if ($this->_level == self::LEVEL_DEVELOPMENT) {
            if ($this->getOption('sql_profiler')) {
                $dbProfiler = Zend_Db_Table::getDefaultAdapter()->getProfiler();
                $dbProfiler->setEnabled(true);
            }
        }
    
    }
    
    /**
     * Because apparently you can't fill in a placeholder after dispatch, I have
     * had to create my own sort of placeholder using a proprietary HTML comment
     * that gets replaced with the debug body.
     */
    public function postDispatch(Zend_Controller_Request_Abstract $request) {
    
        if ($this->_level == self::LEVEL_DEVELOPMENT) {
            $front = Zend_Controller_Front::getInstance();
            $dbProfiler = Zend_Db_Table::getDefaultAdapter()->getProfiler();
            $this->_view->dbProfiler = $dbProfiler;
            $this->_view->post = $request->getPost();
            $this->_view->get = $request->getQuery();
            if ($this->_session) {
                $this->_view->session = $this->_session;
            } else {
                $this->_view->session = $_SESSION;
            }
            $this->_view->cookie = $_COOKIE;
            $template = $this->_view->render($this->getOption('template'));
            $response = Zend_Controller_Front::getInstance()->getResponse();
            $body = str_replace(self::PLACEHOLDER, $template, $response->getBody());
            $response->setBody($body);
        }
    
    }

}